package network;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;

import javax.swing.JOptionPane;

import model.Call;
import model.ChatMessage;
import model.EnumCallStatus;
import model.EnumSignalType;
import model.Signal;
import controller.Controller;

public class TCPService extends Thread {

	private Socket socket;
	private String idTCPService;
	private Call call;
	private Controller controller;
	private boolean running;
	
	public TCPService(Call call, Socket socket, String idTCPService, Controller controller){
		this.call = call;
		this.socket = socket;
		this.idTCPService = idTCPService;
		this.controller=controller;
		this.running=true;
		System.out.println("[TCPService] ["+idTCPService+"] Created");
	}
	//public enum EnumSignalType {CALL_REQUEST, CALL_ACCEPT, CALL_REFUSE,CALL_END,
	//CALL_PAUSE_ON,CALL_PAUSE_OFF, CALL_CHAT_MSG}
	@Override
	public void run() {
		
		while(running){
		try {
			ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
			Signal signalReception = (Signal) ois.readObject();
			EnumSignalType type = signalReception.getMsgType();
			
			switch (type) {
			case CALL_REQUEST:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_REQUEST received");
				call.initCallWithCallRequestSignal(signalReception, this.socket.getInetAddress(),this);
				this.controller.getModel().addCall(call);
				break;
				
			case CALL_ACCEPT:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_ACCEPT received");
				call.setDistUdpPort(signalReception.getUdpListening());
				call.setStatus(EnumCallStatus.ACTIV_ESTABLISHED);
				
				//seter les name dans call
				call.setFirstName(signalReception.getFirstName());
				call.setLastName(signalReception.getLastName());
				call.initCanaux();
				break;
				
			case CALL_CHAT_MSG:
				System.out.println("[TCPService] ["+idTCPService+"] : CHAT_MSG received");
				ChatMessage chatmsg = signalReception.getChatMsg();
				call.getAllChatMessage().add(chatmsg);
				break;
				
			case CALL_END:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_END received");
				
				this.running=false;
				call.getUdpReceiveAndRead().setRunning(false);
//				call.getUdpRecordAndSend().setRunning(false);
				
				Signal signal = new Signal();
				signal.factorySignalCallEndOk();
				this.sendSignal(signal);
				controller.endCall(call, false);
				break;
				
			case CALL_END_OK:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_END_OK received");
				this.running=false;
				try {
				if(this.socket.isConnected()){
				this.socket.close();
				}
				
				} catch (IOException e) {
				e.printStackTrace();
				}
				if(call.getUdpReceiveAndRead().getDatagramSocket() != null){
					call.getUdpReceiveAndRead().getDatagramSocket().close();
				}

				if(call.getUdpReceiveAndRead().getLineHp() != null) {
					call.getUdpReceiveAndRead().getLineHp().drain();
					call.getUdpReceiveAndRead().getLineHp().close();
				}
				
//				if(call.getUdpRecordAndSend().getDatagramSocket() != null){
//					call.getUdpRecordAndSend().getDatagramSocket().close();
//				}
				
//				if(call.getUdpRecordAndSend().getLineMic() != null){
//					call.getUdpRecordAndSend().getLineMic().drain();
//					call.getUdpRecordAndSend().getLineMic().close();
//				}
				
				
				
				
				break;
				
			case CALL_PAUSE_ON:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_PAUSE_ON received");
				call.setStatus(EnumCallStatus.PENDING);
				this.controller.getView().refreshAll();
				JOptionPane.showMessageDialog(null,
						call.getFirstName()+"a mit en pause la conversation", "Information",
						JOptionPane.INFORMATION_MESSAGE);	
				break;
			case CALL_PAUSE_OFF:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_PAUSE_OFF received");
				call.setStatus(EnumCallStatus.ACTIV_ESTABLISHED);
				this.controller.getView().refreshAll();
				JOptionPane.showMessageDialog(null,
						call.getFirstName()+"a retiré la pause", "Information",
						JOptionPane.INFORMATION_MESSAGE);	
				break;
			case CALL_REFUSE:
				System.out.println("[TCPService] ["+idTCPService+"] : CALL_REFUSE received");
				this.controller.getModel().getAllCall().remove(call);
				this.controller.getView().refreshAll();
				JOptionPane.showMessageDialog(null,
						call.getIp().toString()+" refused your call", "Information",
						JOptionPane.INFORMATION_MESSAGE);	
				break;
				
			default:
				
				
				break;
			}
			

			this.controller.getView().refreshAll();
			this.sleep(1000);
		} catch (Exception e) {
			System.out.println("Exception dans TCPService");
			e.printStackTrace();
			this.running=false;
		}
		
		
		
		}
		System.out.println("[TCPService] Sortie de la boucle");
		this.controller.getView().refreshAll();
		System.out.println("TCP Service terminé");

	}
	
	
	public void sendSignal(Signal signal){
		try {
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
			objectOutputStream.writeObject(signal);
			System.out.println("[TCPService] ["+idTCPService+"] : Envoi d'un signal "+signal.getMsgType());
			
		} catch (IOException e) {
			System.out.println("erreur dans TCPService");
		}
	}
	
	
	
	public static void main(String[] args) {
		
//		try {
//			
//			
//			TCPServer tcpServer = new TCPServer(InetAddress.getByAddress(new byte[]{(byte) 192,(byte) 168,0,3}),12000);
//			tcpServer.start();
//			
//			TCPCaller tcpCaller = new TCPCaller(InetAddress.getByAddress(new byte[]{(byte) 192,(byte) 168,0,3}), 12000);
//		} catch (UnknownHostException e) {
//			e.printStackTrace();
//		}
//		
}

	public Socket getSocket() {
		return socket;
	}

	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}
	public Controller getController() {
		return controller;
	}

}
